#include "timeseriesstorage.h"

#include <QTextStream>
#include <QDebug>

TimeSeriesStorage::TimeSeriesStorage(double timeWindow, const QString& persistPath, QObject *parent)
    : QObject(parent)
    , m_timeWindow(timeWindow)
    , m_persistPath(persistPath)
{

}

TimeSeriesStorage::~TimeSeriesStorage()
{
    // 将缓冲区未存储的数据，持久化存储
    trimExpiredData(m_timeSeries.last().timestamp + m_timeWindow);
}

// 添加数据点（自动修剪旧数据）
void TimeSeriesStorage::addData(const QString &curveName, double timestamp, double value)
{
    // 修剪过期数据
    trimExpiredData(timestamp);

    // 查找或创建时间点
    if (m_timeSeries.isEmpty() || m_timeSeries.last().timestamp < timestamp) {
        TimePoint newPoint;
        newPoint.timestamp = timestamp;
        newPoint.values[curveName] = value;
        newPoint.processed = false;
        m_timeSeries.enqueue(newPoint);
    } else {
        // 更新最近时间点的数据
        m_timeSeries.last().values[curveName] = value;
    }

    // 记录存在的曲线
    m_curves.insert(curveName);
}

// 获取未处理数据（按时间窗口）
QList<TimeSeriesStorage::TimePoint> TimeSeriesStorage::getUnprocessedData()
{
    QList<TimePoint> result;

    // 遍历队列找到未处理数据
    for (auto& point : m_timeSeries) {
        if (!point.processed) {
            result.append(point);
            point.processed = true;  // 标记为已处理
        }
    }
    return result;
}

// 获取一个未处理的数据
QPair<double, double> TimeSeriesStorage::getLatestValue(const QString &curveName) const
{
    QPair<double, double> pair;
    if(!m_timeSeries.isEmpty()) {
        for(auto &point : m_timeSeries) {
            if(!point.processed)
                pair.first = point.timestamp;
                pair.second = point.values.value(curveName, 0.0);
                break;  // 找到
        }
    }
    return pair;
}

 // 获取所有曲线名称
QSet<QString> TimeSeriesStorage::getAllCurves() const
{
    return m_curves;
}

// 修剪过期数据（自动持久化）
void TimeSeriesStorage::trimExpiredData(double latestTimestamp)
{
    const double cutoff = latestTimestamp - m_timeWindow;

    while (!m_timeSeries.isEmpty()) {
        const TimePoint& oldest = m_timeSeries.head();

        if (oldest.timestamp >= cutoff) break;


        // 持久化过期数据
        if (!m_persistPath.isEmpty()) {
            persistData(oldest);
        }

        m_timeSeries.dequeue();
    }
}

// 持久化单个时间点数据
void TimeSeriesStorage::persistData(const TimeSeriesStorage::TimePoint &point)
{
    QFile file(m_persistPath);
    if (file.open(QIODevice::Append)) {
        QTextStream stream(&file);

        // 获取所有曲线名称和数据，用一个时间戳存储
        QString curveData;
        for(const QString &curveName : point.values.keys()) {
            curveData.append(QString("(%1,%2),")
                             .arg(curveName)    // 曲线名称
                             .arg(QString::number(point.values.value(curveName), 'f', 3))); //
        }

        // 删除末尾的一个','
        if (!curveData.isEmpty()) {
            curveData.chop(1);
        }
#if 0
        qDebug() << "\n+++++++++++++ 存储到文件 +++++++++++++";
        qDebug() << "timestamp:" << point.timestamp;
        qDebug() << QString("%1,%2")
                    .arg(QDateTime::fromSecsSinceEpoch(point.timestamp).toString("yyyy-MM-dd hh:mm:ss"))
                    .arg(curveData);
        qDebug() << "+++++++++++++++++++++++++++++++++++++\n";
#endif
        // 写入文件，持久化存储，方便回溯维护
        stream << QDateTime::fromSecsSinceEpoch(point.timestamp).toString("yyyy-MM-dd hh:mm:ss") << ","
               << curveData << "\n";
    }
}

// 获取区间长度
void TimeSeriesStorage::setTimeWindow(double timeWindow)
{
    m_timeWindow = timeWindow;
}
